#!/usr/bin/python
from __future__ import print_function
#from gevent import monkey

#monkey.patch_all()
import json
import time
import random
import os
from cgi import parse,parse_qs
#import logging
import sys
import MySQLdb

db_host = "localhost"
db_user = "opensips"
db_pw = "opensipsrw."
db_name = "data_collection"

sys.path.append("/home/dingjun/source/wsgiserver")
import get_info


def handle_root(env, start_response):
    start_response("200 OK",
            [("Content-Type","text/html")]
            )
    return ["<b>hello, world!!!</b>"]

class INFO:
    def __init__(self):
        #self.count = 0
        #self.last_time = time.time()
        pass

    def handle_info(self,env, start_response):
        header=[]
        #header.append(("Content-Type","text/plain"))
        header.append(("Server","pws"))
        header.append(("Cache-Control","no-cache"))
        #header.append(("Last-Visit","%s GMT" % time.asctime(time.gmtime(self.last_time))))

        q=env["QUERY_STRING"]
        q1=parse_qs(q)
        query=dict(
                realtime = 0,
                vendor = "all",
                type = "all",
                name="",
                history = 0,
                date=time.strftime("%Y%m%d"),
                to = 24,
                devtype = "all"
                )

        query["from"] = 0

        for k,v in q1.items():
            query[k.lower().strip()]=v[0].lower().strip()
        names= ["cpu","mem","rx","tx","user","turn"]
        if query["name"] and query["name"] not in names:
            header.append(("Content-Type", "text/html"))
            start_response("400 Bad Request", header)
            return ['<b>wrong paramter: "name" only valid in the follow values: %r</b>' % (names)]

        for k in ["realtime", "history", "date","from","to","getvendor","getdevtype"]:
            if query.has_key(k):
                try:
                    int(query[k])
                except:
                    header.append(("Content-Type", "text/html"))
                    start_response("400 Bad Request", header)
                    return ['<b>wrong paramter: "%s" must be integer</b>' % k]

        if query.has_key("getdevtype"):
            if int(query["getdevtype"]):
                d=self.get_devtype_data(query)
                if d:
                    header.append(("Content-Type","application/json"))
                    start_response("200 OK", header)
                    return [d]

                header.append(("Content-Type","text/html"))
                start_response("404 Not found", header)
                return ["<b>No data found</b>"]
            else:
                header.append(("Content-Type", "text/html"))
                start_response("400 Bad Request", header)
                return ['<b>wrong paramter: "getdevtype" must be greater then zero</b>']


        if query.has_key("getvendor"):
            if int(query["getvendor"]):
                d=self.get_vendor_data(query)
                if d:
                    header.append(("Content-Type","application/json"))
                    start_response("200 OK", header)
                    return [d]

                header.append(("Content-Type","text/html"))
                start_response("404 Not found", header)
                return ["<b>No data found</b>"]
            else:
                header.append(("Content-Type", "text/html"))
                start_response("400 Bad Request", header)
                return ['<b>wrong paramter: "getvendor" must be greater then zero</b>']

        if int(query["realtime"]) and int(query["history"]):
            header.append(("Content-Type", "text/html"))
            start_response("400 Bad Request", header)
            return ['<b>wrong paramter: "realtime" and "history" only one is allowed</b>']

        if int(query["realtime"]) == 0 and query["name"] == "":
            header.append(("Content-Type", "text/html"))
            start_response("400 Bad Request", header)
            return ['<b>wrong paramter: "realtime" or "name" must be specialed</b>']

        types=["phone", "wifidisk", "all"]
        
        if query["name"] == "user" and query["type"] not in types:
            header.append(("Content-Type", "text/html"))
            start_response("400 Bad Request", header)
            return ['<b>wrong paramter: "type" only valid in the follow values: %r</b>' % (types)]

        if int(query["realtime"]):
            d=self.get_realtime_data(query)
            if d:
                header.append(("Content-Type","application/json"))
                start_response("200 OK",header)
                return [d]
            header.append(("Content-Type","text/html"))
            start_response("404 Not found",header)
            return ["<b>No data found</b>"]

        if int(query["from"]) >= int(query["to"]):
            header.append(("Content-Type","text/html"))
            start_response("400 Bad Request",header)
            return ['<b>wrong paramter: "from" must lower than "to"</b>']

        d=self.get_history_data(query)
        if d:
            header.append(("Content-Type","application/json"))
            start_response("200 OK",header)
            return [d]
        header.append(("Content-Type","text/html"))
        start_response("404 Not found",header)
        return ["<b>No data found</b>"]

    def get_realtime_data(self, q):
        data={}

        cpu,mem,rx,tx,o,turn,load=get_info.get_all(0.5,"eth0",q["vendor"],q["type"])


        data["networks"]=dict(
                rx=rx,
                tx=tx
                )
        data["user"]=dict(vendor=q["vendor"],
                num=o,
                type=q["type"])
        data["turn"]=turn
        data["mem"]=mem
        data["sys"]=dict(cpu=cpu,
                load=load
                )
        return json.dumps(data)

    def get_history_data(self,q):
        name=q["name"]
        if name in ["cpu", "mem", "rx", "tx", "turn"]:
            d = self.get_data(q, name)
            return d
        func=getattr(self,"get_%s_data" % name,None)
        if func:
            d=func(q)
            return d
        return ''

    def get_data(self,q,n):
        conn = MySQLdb.connect(db_host, db_user, db_pw, db_name)
        cur = conn.cursor()
        for k in ["devtype","type","history","realtime","vendor"]:
            del q[k]
        data={}
        start=int(q["from"])
        end=int(q["to"])
        date=q["date"]
        d="%s-%s-%s" % (date[:4], date[4:6], date[6:])
        try:
            for i in range(start,end):
                t="%02d:00:00" % i
                t1="%02d:59:59" % (i,)
                sql = "select max(%s) from sys_status where r_time >= '%s' and r_time <= '%s'" % (
                    n,
                    "%s %s" % (d, t),
                    "%s %s" % (d, t1)
                    )
                #print(sql)
                cur.execute(sql)
                res = cur.fetchone()
                if res and res[0]:
                    if n == "turn":
                        data["%02d" % i]=int(res[0])
                    else:
                        data["%02d" % i]=float(res[0])
        finally:
            cur.close()
            conn.close()

        if not data:
            return None
        q["data"]=data

        return json.dumps(q)

    def get_user_data(self,q):
        conn = MySQLdb.connect(db_host, db_user, db_pw, db_name)
        cur = conn.cursor()
        for k in ["history","realtime"]:
            del q[k]
        data={}
        start=int(q["from"])
        end=int(q["to"])
        date=q["date"]
        d="%s-%s-%s" % (date[:4], date[4:6], date[6:])
        vendor_names = []
        cur.execute("select name from vendor_name")
        res = cur.fetchall()
        for r in res:
            vendor_names.append(r[0])
        try:
            for i in range(start,end):
                t="%02d:00:00" % i
                t1="%02d:59:59" % (i,)
                data["%02d" % i] = 0
                for v in vendor_names:
                    sql = "select max(user_num),max(phone_num),max(dev_num) from user_status where r_time >= '%s' and r_time <= '%s' and vendor_name = '%s'" % (
                        #n,
                        "%s %s" % (d, t),
                        "%s %s" % (d, t1),
                        v
                        )
                    #print(sql)
                    cur.execute(sql)
                    res = cur.fetchone()
                    if res:
                        if q["vendor"] == "all":
                            if q["type"] == "all" and res[0]:
                                data["%02d" % i] += int(res[0])
                            elif q["type"] == "phone" and res[1]:
                                data["%02d" % i] += int(res[1])
                            elif q["type"] == "wifidisk" and res[2]:
                                data["%02d" % i] += int(res[2])
                        elif q["vendor"] == v.lower():
                            if q["type"] == "all" and res[0]:
                                data["%02d" % i] += int(res[0])
                            elif q["type"] == "phone" and res[1]:
                                data["%02d" % i] += int(res[1])
                            elif q["type"] == "wifidisk" and res[2]:
                                data["%02d" % i] += int(res[2])
        finally:
            cur.close()
            conn.close()

        if not data:
            return None
        q["data"]=data

        return json.dumps(q)

    def get_vendor_data(self,q):
        conn = MySQLdb.connect(db_host, db_user, db_pw, db_name)
        cur = conn.cursor()
        cur.execute("select name from vendor_name");
        res = cur.fetchall()
        data = []
        for r in res:
            data.append(r[0])
        cur.close()
        conn.close()
        d={}
        d["name"]="vendor"
        d["data"]=data

        return json.dumps(d)

    def get_devtype_data(self,q):
        #data=["SDRJ","WIFI-Disk","WIFIPort","DGRJ","PI-615","WIFISD"]
        data = []
        d={}
        d["name"]="devtype"
        d["data"]=data
        return json.dumps(d)

path_router=[
        ("/",handle_root),
        ("/cgi-bin/info",INFO().handle_info)
        ]

def route_script(env,start_response):
    p=env["PATH_INFO"]
    for path,handler in path_router:
        if path == p:
            return handler(env,start_response);
    start_response("404 Not found",
            [("Content-Type", "text/html")])
    return ["<b>404 Not found</b>"]

info=INFO()

def application(env, start_response):
    return info.handle_info(env, start_response)

if __name__  == "__main__":
    from gevent.pywsgi import WSGIServer
    #print("serving 80...")
    log=open("access.log","a")
    WSGIServer(('',85), route_script).serve_forever()

